<?php
/**
 * The row class.
 *
 */
class Model {
    /**
     * The driver to use.
     * @var Database_Driver
     */
    protected $driver = null;
    /**
     * The table to use. Mainly for models and custom rows.
     * @var string
     */
    protected $table = null;
    /**
     * The row's columns.
     * @var array
     */
    protected $columns = array();
    protected $values = array();
    /**
     * The original row data.
     * @var array
     */
    protected $original = array();
    /**
     * Is row ready only?
     * @var bool
     */
    protected $readonly = true;
    
    /**
     * Constructor.
     * @param Database_Driver $driver
     * @param array $arr
     * @param string $table
     */
    public function __construct(Database_Driver $driver, $arr = array(), $table = null) {
        $this->driver = $driver;
        if($table) {
            $this->table = $table;
            $this->readonly = false;
            foreach($this->columns as $column) {
                $this->values[$column] = $arr[$column];
                $this->original[$column] = $arr[$column];
            }
        } else {
            $this->original = $this->values = $arr;
        }
    }
    
    /**
     * Magic getter to get the value of a field in object notation.
     * @param string $column
     * @return mixed
     */
    public function __get($column) {
        if(in_array($column, $this->columns)) {
            return $this->values[$column];
        }
        return null;
    }
    
    /**
     * Magic setter to set the value of a column if not read only.
     * @param string $column
     * @param mixed $value
     */
    public function __set($column, $value) {
        if($this->readonly) {
            throw new Database_Exception('Row is read only.');
        }
        if(in_array($column, $this->columns)) {
            $this->values[$column] = $value;
        } else {
            throw new Database_Exception("Column '$column' does not exist.");
        }
    }
    
    /**
     * Discard all changes to the row.
     */
    public function discard() {
        $this->columns = $this->original;
    }
    
    /**
     * Save the row.
     */
    public function save() {
        $changes = array();
        foreach($this->values as $key => $value) {
            if($this->original[$key] != $value) {
                $changes[$key] = $value;
            }
        }
        if(count($changes) == 0) {
            return;
        }
        $sql = "UPDATE SET " . $this->table;
        $del = '';
        foreach($changes as $field => $value) {
            $sql .= "$del$field = " . $this->driver->quote($value);
            $del = ', ';
        }
    }
}
?>
